package com.hotlcc.bark.common.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.Week;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.hotlcc.bark.common.exception.BusinessException;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Slf4j
public final class CommonUtil {
    /**
     * 获取真实的className（包括将代理类的名称转为真实类名）
     *
     * @param className
     * @return
     */
    public static String getRealClassName(String className) {
        if (StrUtil.isBlank(className)) {
            return StrUtil.EMPTY;
        }
        return StrUtil.split(className, "$$")[0];
    }

    public static String getRealClassName(Class clazz) {
        if (clazz == null) {
            return StrUtil.EMPTY;
        }
        return getRealClassName(clazz.getName());
    }

    public static String getRealClassName(Object obj) {
        if (obj == null) {
            return StrUtil.EMPTY;
        }
        return getRealClassName(obj.getClass());
    }

    public static String buildMutex(String userUuid, Object obj, String method) {
        return StrUtil.format("{}_{}_{}", userUuid, getRealClassName(obj), method);
    }

    public static <T> T futureGet(Future<T> future) {
        try {
            return future.get();
        } catch (InterruptedException e) {
            log.error("线程终止", e);
            throw new BusinessException("线程终止");
        } catch (ExecutionException e) {
            log.error("线程执行异常", e.getCause());
            throw new BusinessException(e.getCause().getMessage());
        }
    }

    public static <T> T futureGet(Future<T> future, long timeout, TimeUnit unit) {
        try {
            return future.get(timeout, unit);
        } catch (InterruptedException e) {
            log.error("线程终止", e);
            throw new BusinessException("线程终止");
        } catch (ExecutionException e) {
            Throwable cause = e.getCause();
            log.error("线程执行异常", cause);
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            } else {
                throw new BusinessException(e.getCause().getMessage());
            }
        } catch (TimeoutException e) {
            log.error("线程超时", e.getCause());
            throw new BusinessException("数据量大，操作还在进行中，请稍后检查结果");
        }
    }

    @SuppressWarnings("unchecked")
    public static <T> T copyClone(T obj) {
        if (obj == null) {
            return null;
        }
        T copy = (T) ReflectUtil.newInstance(obj.getClass());
        BeanUtil.copyProperties(obj, copy);
        return copy;
    }

    /**
     * 是工作日
     */
    public static boolean isWorkDay(Week week) {
        Assert.notNull(week, "参数错误[week]");
        return week.getValue() > 1 && week.getValue() < 7;
    }
}
